package service

import (
	"context"
	"database/sql"

	"gitee.com/hp-huiw/family-expense-api/internal/constant"
	dbmodel "gitee.com/hp-huiw/family-expense-api/internal/db/model"
	"gitee.com/hp-huiw/family-expense-api/internal/repository"
	"gitee.com/hp-huiw/my-go-core/date"
	"gitee.com/hp-huiw/my-go-core/util"
)

type IncomeExpenseDetailBaseTypeService interface {
	Initialize(ctx context.Context) error
	QueryAll(ctx context.Context) ([]dbmodel.IncomeExpenseDetailBaseType, error)
}

func NewIncomeExpenseDetailBaseTypeService(db *sql.DB) IncomeExpenseDetailBaseTypeService {
	return &incomeExpenseDetailBaseTypeService{
		db:                                    db,
		incomeExpenseDetailBaseTypeRepository: repository.NewIncomeExpenseDetailBaseTypeRepository(db),
	}
}

// Initialize prepares all default types.
func (s *incomeExpenseDetailBaseTypeService) Initialize(ctx context.Context) error {
	exists, err := s.incomeExpenseDetailBaseTypeRepository.Exists(ctx)

	if err != nil {
		return err
	}

	if !exists {
		// region: Expense
		types := []dbmodel.IncomeExpenseDetailBaseType{
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeExpense,
				Name:              constant.ExpenseFamily,
				Title:             "日常家庭各类开销",
				Subtitle:          util.AnyPtr("如超市、用餐、网购等。"),
				OrderIndex:        1,
				AnalysisIncluded:  true,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeExpense,
				Name:              constant.ExpenseLivingCost,
				Title:             "生活成本",
				Subtitle:          util.AnyPtr("如水电煤、通讯费、宽带等。"),
				OrderIndex:        2,
				AnalysisIncluded:  true,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeExpense,
				Name:              constant.ExpenseEducation,
				Title:             "教育",
				Subtitle:          util.AnyPtr("如上课、考试等。"),
				OrderIndex:        3,
				AnalysisIncluded:  true,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeExpense,
				Name:              constant.ExpenseTransportation,
				Title:             "交通",
				Subtitle:          util.AnyPtr("如乘车、交通卡充值、加油卡充值等。"),
				OrderIndex:        4,
				AnalysisIncluded:  true,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeExpense,
				Name:              constant.ExpenseSocializing,
				Title:             "社交",
				Subtitle:          util.AnyPtr("如各类人情、红包等。"),
				OrderIndex:        5,
				AnalysisIncluded:  true,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeExpense,
				Name:              constant.ExpenseFamilyTravel,
				Title:             "家庭旅行",
				Subtitle:          util.AnyPtr("包括相关交通费、住宿费、签证费等。"),
				OrderIndex:        6,
				AnalysisIncluded:  true,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeExpense,
				Name:              constant.ExpenseBusinessTravel,
				Title:             "公务差旅",
				Subtitle:          util.AnyPtr("比如先行个人垫付的相关差旅费用"),
				OrderIndex:        7,
				AnalysisIncluded:  true,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeExpense,
				Name:              constant.ExpenseFamilyCar,
				Title:             "家用车",
				Subtitle:          util.AnyPtr("如车辆维修、保养、车险等。"),
				OrderIndex:        8,
				AnalysisIncluded:  true,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeExpense,
				Name:              constant.ExpenseFamilyInsurance,
				Title:             "家庭保险",
				Subtitle:          util.AnyPtr("如商业养老、意外、疾病类保险等。"),
				OrderIndex:        9,
				AnalysisIncluded:  true,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeExpense,
				Name:              constant.ExpenseFamilyHealth,
				Title:             "家庭健康",
				Subtitle:          util.AnyPtr("如就医、购药、健身等。"),
				OrderIndex:        10,
				AnalysisIncluded:  true,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeExpense,
				Name:              constant.ExpenseInvestment,
				Title:             "投资",
				Subtitle:          util.AnyPtr("如定投、股票、房产等。"),
				OrderIndex:        11,
				AnalysisIncluded:  true,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeExpense,
				Name:              constant.ExpenseCreditCardRepayment,
				Title:             "信用卡还款",
				Subtitle:          util.AnyPtr("用于信用卡账单还款"),
				OrderIndex:        12,
				AnalysisIncluded:  false,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeExpense,
				Name:              constant.ExpensePayForAnother,
				Title:             "代付",
				Subtitle:          util.AnyPtr("用于先行代付的公司、他人的费用。"),
				OrderIndex:        13,
				AnalysisIncluded:  false,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeExpense,
				Name:              constant.ExpenseOther,
				Title:             "其它",
				Subtitle:          util.AnyPtr("其它类费用"),
				OrderIndex:        14,
				AnalysisIncluded:  true,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
		}

		err = s.incomeExpenseDetailBaseTypeRepository.BatchInsert(ctx, types)

		if err != nil {
			return err
		}
		// endregion

		// region: Income
		types = []dbmodel.IncomeExpenseDetailBaseType{
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeIncome,
				Name:              constant.IncomeCompanySalary,
				Title:             "公司薪资收入",
				OrderIndex:        1,
				AnalysisIncluded:  true,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeIncome,
				Name:              constant.IncomeCompanyBonus,
				Title:             "公司奖金收入",
				OrderIndex:        2,
				AnalysisIncluded:  true,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeIncome,
				Name:              constant.IncomeCompanyReimbursement,
				Title:             "公司报销",
				OrderIndex:        3,
				AnalysisIncluded:  false,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeIncome,
				Name:              constant.IncomeCompanyOtherIncome,
				Title:             "公司其它收入",
				OrderIndex:        4,
				AnalysisIncluded:  true,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeIncome,
				Name:              constant.IncomeInvestmentReturn,
				Title:             "投资回报",
				OrderIndex:        5,
				AnalysisIncluded:  true,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeIncome,
				Name:              constant.IncomeRefund,
				Title:             "退款",
				OrderIndex:        6,
				AnalysisIncluded:  true,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeIncome,
				Name:              constant.IncomePayForAnotherRepayment,
				Title:             "代付回款",
				OrderIndex:        7,
				AnalysisIncluded:  false,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
			{
				ID:                util.GenerateUUIDWithoutDashes(),
				IncomeExpenseType: constant.IncomeExpenseTypeIncome,
				Name:              constant.IncomeCompanyOtherIncome,
				Title:             "其它收入",
				OrderIndex:        8,
				AnalysisIncluded:  true,
				DateCreated:       date.GetCurrentDate(),
				LastUpdated:       date.GetCurrentDate(),
			},
		}

		err = s.incomeExpenseDetailBaseTypeRepository.BatchInsert(ctx, types)
		// endregion
	}

	return err
}

// QueryAll queries all IncomeExpenseDetailBaseTypes.
func (s *incomeExpenseDetailBaseTypeService) QueryAll(ctx context.Context) ([]dbmodel.IncomeExpenseDetailBaseType, error) {
	return s.incomeExpenseDetailBaseTypeRepository.QueryAll(ctx)
}

// Container of IncomeExpenseDetailBaseTypeService functions.
type incomeExpenseDetailBaseTypeService struct {
	db                                    *sql.DB
	incomeExpenseDetailBaseTypeRepository repository.IncomeExpenseDetailBaseTypeRepository
}
